import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;

import javax.swing.*; 
import javax.swing.border.Border;

public class draggableLabel extends JLabel implements MouseMotionListener,MouseListener,Serializable {
	
	/**
	 * 
	 */
	private static final int gridStartX = 400;
	private static final int gridStartY = 50;
	private static final long serialVersionUID = 1L;
	static int stoneCount=0;
	ImageIcon icon;
	Point source;
	int xAdjust;
	int yAdjust;
	int xs;
	int ys;
	int initialX;
	int initialY;
	int Xindex;
	int Yindex;
	int prevX;
	int prevY;
	int number;
	boolean moveable;
	String type;
	Color teamColor;
	boolean initial;
public draggableLabel(int X,int Y,ImageIcon icon,String type,Color teamColor,boolean initial,int size) 
{
	this.initial = initial;
	this.type = type;
	setOpaque(false);
	this.teamColor=teamColor;
	this.icon = icon;
	setBounds(X,Y,size,size);
	addMouseMotionListener(this);
	addMouseListener(this);
	source=new Point(X,Y);
	initialX=X;
	initialY=Y;
	moveable = true;
	Xindex=-1;
	Yindex=-1;
}
public int getXindex() {
	return Xindex;
}
public int getYindex() {
	return Yindex;
}
public draggableLabel(int X,int Y,int size,int teamNumber, Color teamColor) 
{
	//super(icon);
	this.type="marker";
	this.number = teamNumber;
	setOpaque(false);
	setBounds(X,Y,size,size);
	addMouseMotionListener(this);
	addMouseListener(this);
	source=new Point(X,Y);
	initialX=X;
	initialY=Y;
	moveable = true;
	Xindex=-1;
	Yindex=-1;
	this.teamColor=teamColor;
}
public draggableLabel(int X,int Y,ImageIcon icon,Color teamColor) 
{
	super(icon);
	setOpaque(false);
	this.type ="donkey";
	this.icon = icon;
	setBounds(X,Y,20,20);
	/*if(teamColor != null)
	{
		this.teamColor = teamColor;
		Border b = BorderFactory.createLineBorder(teamColor, 1);
		this.setBorder(b);
	}*/
	addMouseMotionListener(this);
	addMouseListener(this);
	source=new Point(X,Y);
	initialX=X;
	initialY=Y;
	moveable = true;
	Xindex=-1;
	Yindex=-1;
}
public ImageIcon getImage()
{
	return this.icon;
}
public int getInitialX()
{
	return this.initialX;
}
public int getInitialY()
{
	return this.initialY;
}
public void mousePressed(MouseEvent e)
{
	xAdjust=e.getX();
	yAdjust=e.getY();
	xs=getX();
	ys=getY();
}
public void mouseDragged(MouseEvent e)
{	
	if(moveable)
	{
	int newPositionX = e.getX()+getX()-xAdjust;
	int newPositionY = e.getY()+getY()-yAdjust;
	setLocation(newPositionX,newPositionY);
	
	
	NewSwingApp parent = (NewSwingApp)getParent().getParent().getParent().getParent().getParent();
	parent.getHorizontalLabelsUp().get(prevX).setForeground(Color.black);
	parent.getHorizontalLabelsUp().get(prevX).setBorder(null);
	parent.getHorizontalLabelsDown().get(prevX).setForeground(Color.black);
	parent.getHorizontalLabelsDown().get(prevX).setBorder(null);
	parent.getVerticalLabelsRight().get(prevY).setForeground(Color.black);
	parent.getVerticalLabelsRight().get(prevY).setBorder(null);
	parent.getVerticalLabelsLeft().get(prevY).setForeground(Color.black);
	parent.getVerticalLabelsLeft().get(prevY).setBorder(null);
	// TODO Auto-generated method stub
	int mouseX = newPositionX+xAdjust;
	int mouseY = newPositionY+yAdjust;
		Xindex = (mouseX-gridStartX)/20;
		Yindex = (mouseY-gridStartY)/20;
	if(this.type.equals("marker"))
	{
		Xindex = mouseX;
		Yindex =  mouseY;
	}
	if(mouseX>=gridStartX && mouseY>=gridStartY)
	{
	
		if(Xindex>=0 && Yindex>=0 && Xindex < 40 && Yindex <30)
		{
			//parent.getGridPanel().setVisible(true);
			prevX=Xindex;
			prevY=Yindex;
			Border b = BorderFactory.createLineBorder(Color.red);
			parent.getHorizontalLabelsUp().get(Xindex).setForeground(Color.red);
			parent.getHorizontalLabelsDown().get(Xindex).setForeground(Color.red);
			parent.getVerticalLabelsLeft().get(Yindex).setForeground(Color.red);
			parent.getVerticalLabelsRight().get(Yindex).setForeground(Color.red);
			parent.getHorizontalLabelsUp().get(Xindex).setBorder(b);
			parent.getHorizontalLabelsDown().get(Xindex).setBorder(b);
			parent.getVerticalLabelsLeft().get(Yindex).setBorder(b);
			parent.getVerticalLabelsRight().get(Yindex).setBorder(b);
		}
		//else
		//{
		//	parent.getGridPanel().setVisible(false);
		//}
	}
	//else
	//{
		//parent.getGridPanel().setVisible(false);
	//}
	parent.getLabelsPanel().repaint();
	//System.out.println(mouseX+":"+mouseY+":"+Xindex+":"+Yindex);
	}
}
public void mouseReleased(MouseEvent e)
{
	NewSwingApp parent = (NewSwingApp)getParent().getParent().getParent().getParent().getParent();
	draggableLabel[][] board = parent.getBoard();
	if(Xindex>=0 && Yindex>=0 && Xindex < 40 && Yindex <30)
	{
		System.out.println("here");
		
		parent.getHorizontalLabelsUp().get(prevX).setForeground(Color.black);
		parent.getHorizontalLabelsUp().get(prevX).setBorder(null);
		parent.getHorizontalLabelsDown().get(prevX).setForeground(Color.black);
		parent.getHorizontalLabelsDown().get(prevX).setBorder(null);
		parent.getVerticalLabelsLeft().get(prevY).setForeground(Color.black);
		parent.getVerticalLabelsRight().get(prevY).setForeground(Color.black);
		parent.getVerticalLabelsLeft().get(prevY).setBorder(null);
		parent.getVerticalLabelsRight().get(prevY).setBorder(null);
		
		
		
		
		if(this instanceof Compound)
		{
			Compound oldCompound = (Compound) this;
			if(board[Yindex][Xindex] instanceof Donkey)
			{
				Donkey donkey = (Donkey) board[Yindex][Xindex];
				if(donkey.getTeam().getNumber() == oldCompound.getTeam().getNumber())
				{
					board[Yindex][Xindex].getParent().remove(board[Yindex][Xindex]);
					setLocation(gridStartX+1+Xindex*20,gridStartY+1+Yindex*20);
					moveable = false;
					Compound newCompound = new Compound(this.getInitialX(),this.getInitialY(),this.getImage(),oldCompound.getTeam());
					board[Yindex][Xindex] = oldCompound;
					Action newAction = new Action(oldCompound,oldCompound.getTeam());
					newAction.setReplacedTile(donkey);
					parent.setLastAction(newAction);
					parent.getTilesPanel().add(newCompound);
					parent.getSaveItems().add(new saveItem("compound",gridStartX+1+Xindex*20,gridStartY+1+Yindex*20,Xindex,Yindex,null,false,oldCompound.getTeam().getNumber(),oldCompound.isActive(),false,false,false));
					
				}
				else
				{
					setLocation(xs,ys);
				}
			}
			else
			{
				setLocation(xs,ys);
			}
		}
		if (this instanceof Donkey) {
			Donkey oldDonkey = (Donkey)this;
			
			if(board[Yindex][Xindex] instanceof OilField)
			{
				OilField oilfield = (OilField) board[Yindex][Xindex];
				if(!oilfield.isHasOil())
				{
					
					ImageIcon fixedDonkey ;
					if(!oldDonkey.isFloating())
					{
						 fixedDonkey = new ImageIcon("img/NoddingDonkey/nodding_donkey.png");
					}
					else
					{
						 fixedDonkey = new ImageIcon("img/NoddingDonkey/floating_donkey.png");
					}
					this.setIcon(fixedDonkey);
					oldDonkey.setActive(false);
				}
				else
				{
					oldDonkey.setActive(true);
				}
				board[Yindex][Xindex].getParent().remove(board[Yindex][Xindex]);
				
				setLocation(gridStartX+1+Xindex*20,gridStartY+1+Yindex*20);
				moveable = false;
				
				Donkey newDonkey = new Donkey(this.getInitialX(),this.getInitialY(),this.getImage(),oldDonkey.getTeam(),oldDonkey.isFloating(),true);
				board[Yindex][Xindex] = oldDonkey;
				parent.getTilesPanel().add(newDonkey);
				Action newAction = new Action(oldDonkey,oldDonkey.getTeam());
				newAction.setReplacedTile(oilfield);
				parent.setLastAction(newAction);
				parent.getSaveItems().add(new saveItem("donkey",gridStartX+1+Xindex*20,gridStartY+1+Yindex*20,Xindex,Yindex,null,oldDonkey.isFloating(),oldDonkey.getTeam().getNumber(),oldDonkey.isActive(),false,false,false));
				
			}
			else
			{
				setLocation(xs,ys);
			}
			
		}
		if (this instanceof Pipe) {
			Pipe oldPipe = (Pipe) this;
			
			if(board[Yindex][Xindex] instanceof Road)
			{
				Road road = (Road) board[Yindex][Xindex];
				if(oldPipe.isPerpendicular(road))
				{
					setLocation(gridStartX+1+Xindex*20,gridStartY+1+Yindex*20);
					road.getParent().setComponentZOrder(road, 1);
					road.getParent().setComponentZOrder(this, 0);
					moveable = false;
					
					Pipe newPipe = new Pipe(this.getInitialX(),this.getInitialY(),this.getImage(),oldPipe.getTeam(),oldPipe.getOrientation(),true);
					parent.getTilesPanel().add(newPipe);
					Action newAction = new Action(oldPipe,oldPipe.getTeam());
					parent.setLastAction(newAction);
					parent.getSaveItems().add(new saveItem("pipe",gridStartX+1+Xindex*20,gridStartY+1+Yindex*20,Xindex,Yindex,oldPipe.getOrientation(),false,oldPipe.getTeam().getNumber(),false,false,oldPipe.initial,false));
					//oldPipe.getTeam().setInitial(false);
				}
				else
				{
					setLocation(xs, ys);
				}
			}
			else if (board[Yindex][Xindex] instanceof Pipe)
			{
				Pipe pipe = (Pipe) board[Yindex][Xindex];
				if(oldPipe.isPerpendicular(pipe))
				{
					setLocation(gridStartX+1+Xindex*20,gridStartY+1+Yindex*20);
					pipe.getParent().setComponentZOrder(pipe, 1);
					pipe.getParent().setComponentZOrder(this, 0);
					moveable = false;
					
					Pipe newPipe = new Pipe(this.getInitialX(),this.getInitialY(),this.getImage(),oldPipe.getTeam(),oldPipe.getOrientation(),true);
					parent.getTilesPanel().add(newPipe);
					Action newAction = new Action(oldPipe,oldPipe.getTeam());
					parent.setLastAction(newAction);
					parent.getSaveItems().add(new saveItem("pipe",gridStartX+1+Xindex*20,gridStartY+1+Yindex*20,Xindex,Yindex,oldPipe.getOrientation(),false,oldPipe.getTeam().getNumber(),false,false,oldPipe.initial,false));
					//oldPipe.getTeam().setInitial(false);
				}
				else
				{
					setLocation(xs, ys);
				}
			}
			else if (board[Yindex][Xindex] == null)
			{
				setLocation(gridStartX+1+Xindex*20,gridStartY+1+Yindex*20);
				moveable = false;
				board[Yindex][Xindex] = oldPipe;

				Pipe newPipe = new Pipe(this.getInitialX(),this.getInitialY(),this.getImage(),oldPipe.getTeam(),oldPipe.getOrientation(),true);
				parent.getTilesPanel().add(newPipe);
				Action newAction = new Action(oldPipe,oldPipe.getTeam());
				parent.setLastAction(newAction);
				parent.getSaveItems().add(new saveItem("pipe",gridStartX+1+Xindex*20,gridStartY+1+Yindex*20,Xindex,Yindex,oldPipe.getOrientation(),false,oldPipe.getTeam().getNumber(),false,false,oldPipe.initial,false));
				//oldPipe.getTeam().setInitial(false);
			}
			else
			{
				setLocation(xs, ys);
			}
			
			
		
		}
		if (this instanceof Road) {
			
			Road oldroad = (Road) this;
			
			if(board[Yindex][Xindex] instanceof Road)
			{
				Road road = (Road) board[Yindex][Xindex];
				if(oldroad.isPerpendicular(road))
				{
					setLocation(gridStartX+1+Xindex*20,gridStartY+1+Yindex*20);
					road.getParent().setComponentZOrder(road, 1);
					road.getParent().setComponentZOrder(this, 0);
					moveable = false;
					
					Road newRoad = new Road(this.getInitialX(),this.getInitialY(),this.getImage(),oldroad.getOrientation(),oldroad.isBridge());
					parent.getTilesPanel().add(newRoad);
					Action newAction = new Action(oldroad);
					parent.setLastAction(newAction);
					parent.getSaveItems().add(new saveItem("road",gridStartX+1+Xindex*20,gridStartY+1+Yindex*20,Xindex,Yindex,oldroad.getOrientation(),false,-1,false,false,false,oldroad.isBridge()));
				}
				else
				{
					setLocation(xs, ys);
				}
			}
			else if (board[Yindex][Xindex] instanceof Pipe)
			{
				Pipe road = (Pipe) board[Yindex][Xindex];
				if(oldroad.isPerpendicular(road))
				{
					setLocation(gridStartX+1+Xindex*20,gridStartY+1+Yindex*20);
					road.getParent().setComponentZOrder(road, 1);
					road.getParent().setComponentZOrder(this, 0);
					moveable = false;
					
					Road newRoad = new Road(this.getInitialX(),this.getInitialY(),this.getImage(),oldroad.getOrientation(),oldroad.isBridge());
					parent.getTilesPanel().add(newRoad);
					Action newAction = new Action(oldroad);
					parent.setLastAction(newAction);
					parent.getSaveItems().add(new saveItem("road",gridStartX+1+Xindex*20,gridStartY+1+Yindex*20,Xindex,Yindex,oldroad.getOrientation(),false,-1,false,false,false,oldroad.isBridge()));
				}
				else
				{
					setLocation(xs, ys);
				}
			}
			else if (board[Yindex][Xindex] == null)
			{
				setLocation(gridStartX+1+Xindex*20,gridStartY+1+Yindex*20);
				moveable = false;
				board[Yindex][Xindex] = oldroad;

				Road newRoad = new Road(this.getInitialX(),this.getInitialY(),this.getImage(),oldroad.getOrientation(),oldroad.isBridge());
				parent.getTilesPanel().add(newRoad);
				Action newAction = new Action(oldroad);
				parent.setLastAction(newAction);
				parent.getSaveItems().add(new saveItem("road",gridStartX+1+Xindex*20,gridStartY+1+Yindex*20,Xindex,Yindex,oldroad.getOrientation(),false,-1,false,false,false,oldroad.isBridge()));

				
			}
			else
			{
				setLocation(xs, ys);
			}
			
			/*Road oldRoad = (Road) this;
			setLocation(gridStartX+1+Xindex*20,gridStartY+1+Yindex*20);
			board[Yindex][Xindex] = this;
			Road newRoad = new Road(this.getInitialX(),this.getInitialY(),this.getImage(),oldRoad.getOrientation());
			parent.getTilesPanel().add(newRoad);*/
		}
		
		if(this instanceof OilField)
		{
			OilField oilField = (OilField) this;
			if(board[Yindex][Xindex] == null)
			{
				setLocation(gridStartX+1+Xindex*20,gridStartY+1+Yindex*20);
				board[Yindex][Xindex] = oilField;
				int oldXindex = (xs-gridStartX)/20;
				int oldYindex = (ys-gridStartY)/20;
				board[oldYindex][oldXindex] = null;
				Action newAction = new Action(oilField);
				parent.setLastAction(newAction);
				int saveItemIndex = parent.getSaveItem(xs, ys);
				parent.getSaveItems().get(saveItemIndex).setXIndex(Xindex);
				parent.getSaveItems().get(saveItemIndex).setYIndex(Yindex);
				parent.getSaveItems().get(saveItemIndex).setXPosition(gridStartX+1+Xindex*20);
				parent.getSaveItems().get(saveItemIndex).setYPosition(gridStartY+1+Yindex*20);
				
				//TODO add undo and save
			}
			else
			{
				setLocation(xs, ys);
			}
		}
		
		parent.getTilesPanel().repaint();
		
	}
	else if(this instanceof OilField)
	{
		int oldXindex = (xs-gridStartX)/20;
		int oldYindex = (ys-gridStartY)/20;
		board[oldYindex][oldXindex].getParent().remove(board[oldYindex][oldXindex]);
		board[oldYindex][oldXindex] = null;
		parent.getSaveItems().remove(parent.getSaveItem(xs, ys));
		//TODO add undo and save 
	}
	else
	{
		if(this.type!="marker")
		{
			setLocation(xs,ys);
		}
		else
		{
			setLocation(getX(),getY());
			int saveItemIndex = parent.getSaveItem(xs, ys,number);
			parent.getSaveItems().get(saveItemIndex).setXPosition(getX());
			parent.getSaveItems().get(saveItemIndex).setYPosition(getY());
		}
	}
	
}


public void setMoveable(boolean moveable) {
	this.moveable = moveable;
}
public void mouseEntered(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}

public void paintComponent(Graphics g) {
	
	if(this.type.equals("donkey"))
	{
		if(this instanceof Donkey)
		{
			Donkey donkey = (Donkey) this;
			String number = donkey.getTeam().getNumber()+"";
			g.setColor(Color.black);
			g.setFont(getFont().deriveFont(8.0f));
			g.drawChars(number.toCharArray(), 0, number.length(), 3, 9);
		}
	}
	if(this.type.equals("marker"))
	{
		g.setColor(teamColor);
	    g.fillRect(3, 3, 37, 37);
	    String teamString = "Team";
	    String number = this.number+"";
	    if(teamColor == Color.black)
	    	g.setColor(Color.white);
	    else
		g.setColor(Color.black);
		g.setFont(getFont().deriveFont(10.0f));
		g.drawChars(teamString.toCharArray(), 0, teamString.length(), 7, 16);
		g.drawChars(number.toCharArray(), 0, number.length(), 15, 30);
		 Border b = BorderFactory.createLineBorder(Color.WHITE, 3);
		 b.paintBorder(this, g, 0, 0, 40, 40);
	}
	else
	if(!(this.type.equals("donkey")))
	{
	g.drawImage(icon.getImage(), 0, 0, icon.getImage().getWidth(this),icon.getImage().getHeight(this),this );
	if(this.type.equals("pipe"))
	{
		if(this.initial)
		{
			Pipe thisPipe = (Pipe) this;
			String number = thisPipe.getTeam().getNumber()+"";
			g.setColor(Color.black);
			g.setFont(getFont().deriveFont(8.0f));
			g.drawChars(number.toCharArray(), 0, number.length(), 0, 6);
		}
	g.setColor(teamColor);
    g.fillRect(6, 6, 7, 7);
    Color c = new Color(255,234,168);
    Border b = BorderFactory.createLineBorder(c, 1);
    b.paintBorder(this, g, 6, 6, 7, 7);
	}
	}
    super.paintComponent(g);
  }

}

